<?php

namespace App\Http\Controllers\Manage;

use App\Http\Controllers\ApiController;
use App\Http\Requests\DiagnoseStoreRequest;
use App\Http\Requests\DiagnoseUpdateRequest;
use App\Http\Requests\PatientOrRecordRequest;
use App\Models\CnDiagnose;
use App\Models\MedicalDiagnose;
use App\Models\MedicalRecord;
use App\Project\Transform;
use App\Transformers\MedicalDiagnoseTransformer;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Http\Request;

/**
 * 诊断项目控制器
 * Class DiagnoseController
 * @package App\Http\Controllers\Manage
 */
class DiagnoseController extends ApiController
{
    /**
     * @param \App\Http\Requests\DiagnoseStoreRequest $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function store(DiagnoseStoreRequest $request)
    {
        $input = $request->input();

        $result = MedicalDiagnose::updateOrCreate(['record_id' => $input['record_id']], $input);

        $cndiagnoses = $request->input('cndiagnoses');
        if (empty($cndiagnoses)) {
            $cndiagnoses = [];
        }
        $this->parseCnDiagnoses($cndiagnoses, $input['record_id']);

        return $this->response(['id' => $result['id']]);
    }

    /**
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function edit(Request $request)
    {
        $data = null;
        $id   = $request->get('id');

        if ($id > 0) {

            $data = MedicalDiagnose::findOrFail($id);
        } elseif ($record_id = $request->get('record_id')) {
            $data = MedicalDiagnose::where(['record_id' => $record_id])->first();
        } else {
            abort(400, '缺失诊断ID，或者病历ID');
        }

        if (empty($data)) {
            throw (new ModelNotFoundException())->setModel(MedicalDiagnose::class);
        }

        return $this->item($data, new MedicalDiagnoseTransformer());
    }

    /**
     * @param \App\Http\Requests\DiagnoseUpdateRequest $request
     * @return \Illuminate\Http\JsonResponse
     * @throws \Exception
     */
    public function update(DiagnoseUpdateRequest $request)
    {
        $where = [];

        if ($id = $request->input('id')) {
            $where['id'] = $id;
        } else {
            $where['record_id'] = $request->input('record_id');
        }

        $input = $request->except(['id', 'record_id', 'cndiagnoses']);

        $input = (new Transform())->setArray($input)
                                  ->convertArrayToString(['diagnose'])
                                  ->convertArrayToJson(['cn_diagnose'])
                                  ->get();

        $result = MedicalDiagnose::where($where)->update($input);
        $cndiagnoses = $request->input('cndiagnoses');
        if (empty($cndiagnoses)) {
            $cndiagnoses = [];
        }
        $this->parseCnDiagnoses($cndiagnoses, $request->input('record_id'));

        return $this->responseForUpdate($result);
    }

    /**
     * @param array $cnDiagnoses
     * @param       $record_id
     * @throws \Exception
     */
    protected function parseCnDiagnoses(array $cnDiagnoses, $record_id)
    {
        $ids = array_filter(collect($cnDiagnoses)->pluck('id')->toArray());

        if ($ids) {
            CnDiagnose::whereNotIn('id', $ids)->where('record_id', $record_id)->delete();
        } else {
            CnDiagnose::where('record_id', $record_id)->delete();
        }

        foreach ($cnDiagnoses as $cnDiagnose) {
            if (isset($cnDiagnose['carry_key']))
                $cnDiagnose['carry_key'] = implode(',', $cnDiagnose['carry_key']);

            if (isset($cnDiagnose['id'])) {
                CnDiagnose::where('id', $cnDiagnose['id'])->update($cnDiagnose);
            } else {
                CnDiagnose::create($cnDiagnose + compact('record_id'));
            }
        }
    }

    /**
     * 获取上一次看诊，诊断的信息
     * @param \App\Http\Requests\PatientOrRecordRequest $request
     * @return \Illuminate\Http\JsonResponse
     */
    public function previous(PatientOrRecordRequest $request)
    {
        $input = $request->only('patient_id', 'record_id');

        if ($input['record_id']) {

            return $this->previousWithRecordId($input['record_id']);
        }

        return $this->previousWithPatientId($input['patient_id']);
    }

    /**
     * @param $record_id
     * @return \Illuminate\Http\JsonResponse
     */
    protected function previousWithRecordId($record_id)
    {
        $record = new MedicalRecord();

        try {
            $previous = $record->previous($record_id);
        } catch (\InvalidArgumentException $exception) {
            return $this->setMessage($exception->getMessage())
                        ->setCode(40400)
                        ->hasNoData();
        }

        $columns = ['diagnose', 'remark'];
        $isWestern = app('scene')->isWestern();
        if (!$isWestern) {
            $columns[] = 'cndiagnoses';
        }

        $response = MedicalDiagnose::where('record_id', $previous->id)->first($columns);
        if (is_null($response)) {
            return $this->hasNoData();
        }

        if (!$isWestern) {
            $response->cndiagnoses = $response->cnDiagnoses();
        }

        return $this->hasData($response);
    }

    /**
     * @param $patient
     * @return \Illuminate\Http\JsonResponse
     */
    protected function previousWithPatientId($patient)
    {
        $record_id = MedicalRecord::previousWithPatient($patient)->first(['id']);

        $columns = ['diagnose', 'remark'];
        $isWestern = app('scene')->isWestern();
        if (!$isWestern) {
            $columns[] = 'cndiagnoses';
        }

        $response = MedicalDiagnose::where('record_id', $record_id->id)->first($columns);
        if (is_null($response)) {
            return $this->hasNoData();
        }
        if (!$isWestern) {
            $response->cndiagnoses = $response->cnDiagnoses();
        }

        return $this->hasData($response);
    }
}
